package broth.gdt;

import java.util.HashMap;

import android.app.SearchManager;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.provider.BaseColumns;
import android.util.Log;

public class TrackDatabase{
	private static final String TAG = "TrackDatabase";
	
	// the columns we'll include in the dictionary table
	public static final String KEY_WORD = SearchManager.SUGGEST_COLUMN_TEXT_1;
	public static final String KEY_DEFINITION = SearchManager.SUGGEST_COLUMN_TEXT_2;
	
	private static final String DATABASE_NAME = "track";
	private static final String FTS_VIRTUAL_TABLE = "FTStrack";
	private static final int DATABASE_VERSION = 2;
	
	private final TrackOpenHelper mDatabaseOpenHelper;
	private static final HashMap<String, String> mColumnMap = buildColumnMap();
	
	// constructor that provides the working context
	public TrackDatabase(Context context) {
		mDatabaseOpenHelper = new TrackOpenHelper(context);
	}
	
	// builds a column map to be given to the query builder
	private static HashMap<String,String> buildColumnMap() {
		HashMap<String,String> map = new HashMap<String,String>();
		map.put(KEY_WORD, KEY_WORD);
		map.put(KEY_DEFINITION, KEY_DEFINITION);
		map.put(BaseColumns._ID, "rowid AS " + BaseColumns._ID);
		map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + 
				SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
		map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "rowid AS " +
				SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
		return map;
	}
	
	// returns a cursor to the word at rowId
	public Cursor getWord(String rowId, String[] columns) {
		String selection = "rowid = ?";
		String[] selectionArgs = new String[] {rowId};
		
		// query looks like: SELECT <columns> FROM <table> WHERE rowid = <rowId>
		return query(selection, selectionArgs, columns);
	}
	
	// returns a cursor to all words that match query
	public Cursor getWordMatches(String query, String[] columns) {
		String selection = KEY_WORD + " MATCH ?";
		String[] selectionArgs = new String[] {query+"*"};
		
		// query looks like: SELECT <columns> FROM <table> WHERE <KEY_WORD> MATCH 'query*'
		return query(selection, selectionArgs, columns);
	}
	
	// performs a database query
	private Cursor query(String selection, String[] selectionArgs, String[] columns) {
		SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
		builder.setTables(FTS_VIRTUAL_TABLE);
		builder.setProjectionMap(mColumnMap);
		
		Cursor cursor = builder.query(mDatabaseOpenHelper.getReadableDatabase(),
				columns, selection, selectionArgs, null, null, null);
		
		if (cursor == null) {
			return null;
		}
		else if (!cursor.moveToFirst()) {
			cursor.close();
			return null;
		}
		return cursor;
	}
	
	// class to create/open the database
	private static class TrackOpenHelper extends SQLiteOpenHelper {
		
		private final Context mHelperContext;
		private SQLiteDatabase mDatabase;
		
		// string to create the FTS virtual table
		private static final String FTS_TABLE_CREATE =
				"CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
				" USING fts3 (" +
				KEY_WORD + ", " +
				KEY_DEFINITION + ");";
		
		// constructor that gets the working context
		TrackOpenHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
			mHelperContext = context;
		}
		
		@Override
		public void onCreate(SQLiteDatabase db) {
			mDatabase = db;
			mDatabase.execSQL(FTS_TABLE_CREATE);
		}
		
		public long addWord(String word, String definition) {
			ContentValues initialValues = new ContentValues();
			initialValues.put(KEY_WORD, word);
			initialValues.put(KEY_DEFINITION, definition);
			
			return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
		}
		
		@Override
		public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
					+ newVersion + ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
			onCreate(db);
		}
		
	}

}
